package com.controller.user;

import com.alipay.api.AlipayApiException;
import com.config.ProjConfig;
import com.entity.Order;
import com.pay.Service.AliPayService;
import com.pay.prjo.AliPayAsyncVo;
import com.pay.prjo.AliPayParam;
import com.service.user.OrderService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.util.*;

import javax.servlet.http.HttpServletRequest;

/**
 * 响应和买家订单相关的请求
 *
 * 
 */
@RestController
@CrossOrigin
public class OrderController {

  public static final String ORDER_PAY_NOTIFY_URL = ProjConfig.host + "/orderPay/notify";
  private static Map<String, String[]> allPayingOrder = new HashMap<>(100);
  /**
   * 说明，订单状态只包括OrderDao中的： all = 0; waitPay = 1; waitDelivery = 2; waitGoods = 3; waitComment = 4;
   * complete = 5;
   */
  @Autowired OrderService orderService;

  @Autowired AliPayService aliPayService;

  /**
   * 获取生成订单所需的信息
   *
   * @param goodIds 商品编号数组
   * @return 生成订单所需的信息，包括商品基本信息和卖家
   */
  @GetMapping("order/getCreateOrdersInfo")
  public List<Map<String, Object>> getCreateOrdersInfo(
      @RequestParam("goodIds[]") String[] goodIds) {
    return orderService.getCreateOrdersInfo(goodIds);
  }

  /**
   * 获取生成订单所需的信息
   *
   * @param goodId 商品编号
   * @return 生成订单所需的信息，包括商品基本信息和卖家
   */
  @GetMapping("order/getCreateOrderInfo")
  public Map<String, Object> getCreateOrderInfo(@RequestParam("goodId") String goodId) {
    return orderService.getCreateOrderInfo(goodId);
  }

  /**
   * 提交订单
   *
   * @param userId 用户编号
   * @param goodId 商品编号
   * @param goodNum 商品数目
   * @param tradeWay 交易方式，'线上'或'线下'
   * @param grId 收货信息编号 若为线下交易，则收货信息编号为""或“undefined”即可
   * @param remark 备注
   * @return 生成订单返回订单号
   */
  @PostMapping("order/submitOrder")
  public String submitOrder(
      @RequestParam("userId") String userId,
      @RequestParam("goodId") String goodId,
      @RequestParam("goodNum") int goodNum,
      @RequestParam("tradeWay") String tradeWay,
      @RequestParam("grId") String grId,
      @RequestParam("remark") String remark) {
    if (grId.equals("undefined") || grId.equals("")) {
      grId = null;
    }
    return orderService.addAOrder(userId, goodId, goodNum, tradeWay, grId, remark);
  }

  /**
   * 获取自己的卖书数目
   *
   * @param userId 用户编号
   * @param orderStatus 订单状态
   * @return 对应状态的订单数目
   */
  @PostMapping("order/getOrderCount")
  public String getOrderCount(
      @RequestParam("userId") String userId, @RequestParam("orderStatus") int orderStatus) {
    int count = orderService.getBuyerOrderCount(userId, orderStatus);
    return String.valueOf(count);
  }

  @PostMapping("getOrderById")
  public Order getOrderById(@RequestParam("orderId") String orderId) {
    return orderService.getOrdersByIds(Arrays.asList(orderId)).get(0);
  }
  /**
   * 获取自己的卖书订单
   *
   * @param userId 用户编号
   * @param orderStatus 订单状态
   * @param pageSize 页大小
   * @param pageIndex 页索引
   * @return 订单列表
   */
  @PostMapping("order/getOrders")
  public List<Order> getOrders(
      @RequestParam("userId") String userId,
      @RequestParam("orderStatus") int orderStatus,
      @RequestParam("pageSize") int pageSize,
      @RequestParam("pageIndex") int pageIndex) {
    return orderService.getBuyerOrders(userId, orderStatus, pageSize, pageIndex);
  }

  // 待收货订单确认收货

  /**
   * 取消订单 当且仅当订单状态为waitPay时才能被取消
   *
   * @param userId 用户编号
   * @param orderId 订单编号
   * @return 取消成功返回1，失败返回0
   */
  @PostMapping("order/cancelOrder")
  public String cancelOrder(
      @RequestParam("userId") String userId, @RequestParam("orderId") String orderId) {
    int ret = orderService.deleteOrder(userId, orderId);
    return String.valueOf(ret);
  }

  /**
   * 用
   *
   * @param orderIds 订单编号列表
   * @param totalNum 总价
   * @param userId 用户名
   * @return 支付成功返回 ，失败返回0
   */
  @PostMapping("order/payWithCoin")
  public String payWithCoin(
      @RequestParam("orderIds[]") String[] orderIds,
      @RequestParam("totalNum") float totalNum,
      @RequestParam("userId") String userId) {
    int ret = orderService.payWithCoin(userId, orderIds, totalNum);
    return String.valueOf(ret);
  }

  // TODO
  @PostMapping("order/urgedDelivery")
  public String urgedDelivery(
      @RequestParam("userId") String userId, @RequestParam("orderId") String orderId) {
    int ret = orderService.urgedDelivery(orderId);
    return String.valueOf(ret);
  }

  /**
   * 待收货订单确认收货 当且仅当订单状态为waitGoods时才能被取消
   *
   * @param userId 用户编号
   * @param orderId 订单编号
   * @return 确认成功返回1，失败返回0
   */
  @PostMapping("order/confirmGoods")
  public String confirmGoods(
      @RequestParam("userId") String userId, @RequestParam("orderId") String orderId) {
    int ret = orderService.confirmGood(orderId);
    return String.valueOf(ret);
  }

  @PostMapping("order/getOrderPayQrCode")
  public String getOrderPayQrCode(
      @RequestParam("returnURL") String returnURL,
      @RequestParam("orderIds[]") String[] orderIds,
      @RequestParam("totalNum") float totalNum,
      Integer restMinutes) {
    String payId;
    if (orderIds.length == 1) {
      payId = orderIds[0];
    } else {
      payId = UUID.randomUUID().toString().replace("-", "");
    }

    AliPayParam param = new AliPayParam();
    param.setOutTradeNo(payId);
    param.setSubject("书湘二手书交易平台支付");
    param.setTotalAmount(totalNum);
    if (restMinutes == null) {
      restMinutes = 29 - orderService.getWaitPayMaxPastMinutes(orderIds);
    }
    param.setTimeOut(restMinutes + "m");
    param.setNotifyUrl(ORDER_PAY_NOTIFY_URL);
    param.setReturnUrl(returnURL);

    String qrCode = aliPayService.pay(param, null);
    // 添加正在支付订单记录
    if (qrCode != null) {
      allPayingOrder.put(payId, orderIds);
    }
    return qrCode;
  }

  /**
   * 异步结果通知回调方法
   *
   * @param result 支付宝异步通知返回的结果
   * @param request request
   * @return 是否验签通过
   */
  @PostMapping("/orderPay/notify")
  public String handleAliPayed(AliPayAsyncVo result, HttpServletRequest request)
      throws UnsupportedEncodingException, AlipayApiException {
    return aliPayService.checkV1(
        result,
        () -> {
          System.out.println("订单现金支付购买成功");
          orderService.orderPaySuccess(allPayingOrder.get(result.getOut_trade_no()));
        },
        () -> allPayingOrder.remove(result.getOut_trade_no()));
  }
}
